// 引入登录 | 退出登录 | 获取用户信息 的接口函数
import { login, logout, getInfo } from '@/api/user'
// 获取token | 设置token | 删除token的函数
import { getToken, setToken, removeToken } from '@/utils/auth'
// 路由模块当中重置路由的方法
import { resetRouter, asyncRoutes, constantRoutes, anyRoutes } from '@/router'
import router from '@/router'
import cloneDeep from 'lodash/cloneDeep'

const getDefaultState = () => {
  return {
    // 获取token
    token: getToken(),
    // 存储用户名字
    name: '',
    // 存储用户的头像
    avatar: '',
    // 菜单标记--服务器返回的菜单信息【根据不同的角色：返回的标记信息，数组里面的元素是字符串】
    routes: [],
    // 角色信息
    roles: [],
    // 按钮权限的信息
    buttons: [],
    // 对比之后【项目中已有的异步路由，与服务器返回的标记信息进行对比，最终需要展示的路由】
    resultAsyncRoutes: [],
    // 用户最终需要展示的全部路由
    resultAllRoutes: []
  }
}

const state = getDefaultState()

// 唯一修改state的地方
const mutations = {
  // 重置state
  RESET_STATE: (state) => {
    // 清除数据方法（合并清空）
    Object.assign(state, getDefaultState())
  },
  // 存储token
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  // // 存储用户名
  // SET_NAME: (state, name) => {
  //   state.name = name
  // },
  // // 存储用户的头像
  // SET_AVATAR: (state, avatar) => {
  //   state.avatar = avatar
  // }
  // 存储用户信息
  SET_USERINFO: (state, userInfo) => {
    // 用户名
    state.name = userInfo.name
    // 用户头像
    state.avatar = userInfo.avatar
    // 菜单权限的标记
    state.routes = userInfo.routes
    // 按钮权限的标记
    state.buttons = userInfo.buttons
    // 角色信息
    state.roles = userInfo.roles
  },
  // 最终计算出来的异步路由
  SET_RESULTASYNCROUTES: (state, asyncRoutes) => {
    // vuex保存当前用户的异步路由，注意：一个用户需要展示完整的路由包含：常量路由、异步路由、任意路由
    state.resultAsyncRoutes = asyncRoutes
    // 计算出当前用户需要展示的所有路由【常量路由合并--异步路由与任意路由】
    state.resultAllRoutes = constantRoutes.concat(state.resultAsyncRoutes, anyRoutes)
    // console.log('全部路由的展示', state.resultAllRoutes)
    // 给路由器添加新的路由 --- 先引入路由文件
    router.addRoutes(state.resultAllRoutes)
    // console.log('看问题1', router.selfaddRoutes)
    // console.log('看问题2', router.options.routes)
    // console.log('看问题3', state.resultAllRoutes)
    // router.selfaddRoutes(state.resultAllRoutes)
    // next({ ...to })
  }
}

// 定义一个函数：两个数组进行对比【asyncRoutes|data.routes】，对比出当前的用户到底显示出哪些异步路由
const computedAsyncRoutes = (asyncRoutes, routes) => {
  // console.log('路由的对比', asyncRoutes, routes)
  // 过滤数组：过滤出当前用户【超级管理|普通员工】需要展示的异步路由
  return asyncRoutes.filter(item => {
    // 每个真实的异步路由
    // console.log('item', item)
    // ===-1 数组中没有这个元素， ！==-1表示要展示的元素
    // 数组中没有这个元素返回索引值 -1， 如果有这个元素返回的索引值一定不是 -1
    if (routes.indexOf(item.name) !== -1) {
      // alert(11)
      // 递归搜索路由：别忘记还有二级、三级...路由
      if (item.children && item.children.length) {
        item.children = computedAsyncRoutes(item.children, routes)
      }
      return true
    }
  })
}

// 异步处理state业务
const actions = {
  // user login
  // 处理登录的业务
  async login({ commit }, userInfo) {
    // 解构出用户名与密码
    const { username, password } = userInfo
    const result = await login({ username: username.trim(), password: password })
    console.log('登录', result)
    // 注意，当前登录请求现在使用的是mock数据，mock数据的code是20000
    if (result.code === 20000) {
      // vuex存储token
      commit('SET_TOKEN', result.data.token)
      // 持久化存储token(这里用的是cookies)
      setToken(result.data.token)
      return 'ok'
    } else {
      return Promise.reject(new Error(result.data.message))
    }
    // return new Promise((resolve, reject) => {
    //   login({ username: username.trim(), password: password }).then(response => {
    //     const { data } = response
    //     commit('SET_TOKEN', data.token)
    //     setToken(data.token)
    //     resolve()
    //   }).catch(error => {
    //     reject(error)
    //   })
    // })
  },

  // get user info
  // 获取用户的信息
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token).then(response => {
        // 获取用户的信息：返回的数据包含---用户名name、用户头像avatar、routes【服务器返回的标志：不同的用户应该展示哪些菜单的标记】、role（用户角色的信息）
        // button【按钮信息：按钮权限用的信息】
        const { data } = response
        // console.log('用户信息data', data)

        // if (!data) {
        //   return reject('Verification failed, please Login again.')
        // }

        // const { name, avatar } = data
        // commit('SET_NAME', name)
        // commit('SET_AVATAR', avatar)

        // vuex存储用户的全部信息
        commit('SET_USERINFO', data)
        commit('SET_RESULTASYNCROUTES', computedAsyncRoutes(asyncRoutes, data.routes))
        // commit('SET_RESULTASYNCROUTES', computedAsyncRoutes(cloneDeep(asyncRoutes), data.routes))
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  // user logout
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token).then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // remove token
  resetToken({ commit }) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

